package ez

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"os"
	//_ "net/http/pprof"
)

var serverChan chan int

func Run() {
	DispatchToManySync(EventBeforeConfigReady, nil, context.TODO())
	DispatchToManySync(EventAfterConfigReady, nil, context.TODO())
	DispatchToManySync(EventBeforeServerRun, nil, context.TODO())
	handler := NewServerHandler()
	for url, dir := range ConfigServer.FileServers {
		serveFile("/"+url+"/", dir)
		serveFile("/"+url, dir)
	}
	http.Handle("/", handler)
	http.HandleFunc("/_stop", func(writer http.ResponseWriter, request *http.Request) {
		//todo 服务器中止的权限验证
		LogToConsole(fmt.Sprintf("收到停止服务请求:%v", request))
		Stop()
	})
	LogToConsoleNoTrace(fmt.Sprintf("配置文件中启动的运行端口为：%d", ConfigServer.ServerPort))

	serverChan = make(chan int)
	l, e := net.Listen("tcp", fmt.Sprintf("%s:%d", ConfigServer.ServerHost, ConfigServer.ServerPort))
	if e != nil {
		LogToConsole("服务启动时发生错误")
		PrintError(e)
	}
	go func() {
		defer func() { serverChan <- 1 }()
		e = http.Serve(l, nil)
		if e != nil {
			LogToConsole("服务启动时发生错误")
			PrintError(e)
		}
	}()

	if ConfigServer.UserTLS {
		lTls, e := net.Listen("tcp", fmt.Sprintf("%s:443", ConfigServer.ServerHost))
		e = http.ServeTLS(lTls, nil, ConfigServer.CertFile, ConfigServer.KeyFile)
		if e != nil {
			LogToConsole("HTTPS服务启动时发生错误")
			PrintError(e)
		}
	}
	//自动获取端口
	ConfigServer.ServerPort = l.Addr().(*net.TCPAddr).Port
	LogToConsoleNoTrace(fmt.Sprintf("启动后获取到的真实端口为：%d", ConfigServer.ServerPort))
	//自动获取运行时的文件路径
	if ConfigServer.ServerRoot == "" {
		ConfigServer.ServerRoot, _ = os.Getwd()
		LogToConsoleNoTrace(fmt.Sprintf("自动获取到运行时的文件路径为：%s", ConfigServer.ServerRoot))
	}
	DispatchToManySync(EventAfterServerRun, nil, context.TODO())
	<-serverChan
}

func Stop() {
	serverChan <- 1
}
